#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>

#include <assert.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include "hi_unf_pmoc.h"
#include "drv_ir.h"
#include "basic_datatype.h"
/*
when you want use your x5hdtest.bin, please re-define USR_BIN_SWITCH to 1.
Also don't forget put x5hdtest.bin to this path: "SDK\sample\pmoc"
*/
#define USR_BIN_SWITCH 0

#ifdef CONFIG_SUPPORT_CA_RELEASE
#define HI_INFO_PMOC(format, arg ...)
#else
#define HI_INFO_PMOC(format, arg ...) LOGD( format, ## arg)
#endif

static HI_U32 g_u32CodeSize = 0;
static HI_U8 g_u8BinBuf[0x10000];  /*64KB buffer*/

static HI_U32 g_TimerCount = 0;
static HI_U8 g_DisplayMode = 2;
static HI_U32 g_RunningCount = 1;
static HI_U8 g_Scene = 0;
static HI_U8 g_IrType = 0;
static HI_U8 g_KeyledType = 2;
static const char PID_FILE[] = "/dev/wifi/sample.pid";

HI_S32 LoadUsrBin(HI_VOID)
{
    FILE *fb;
    HI_U32 len;

    fb = fopen("./x5hdtest.bin", "r");
    if (NULL == fb)
    {
        HI_INFO_PMOC("open file x5hdtest.bin failed!\n");
        return HI_FAILURE;
    }

    fseek(fb, 0, SEEK_END);
    len = (HI_U32)ftell(fb);
    HI_INFO_PMOC("pmoc code len = %d \n", len);
    if (len > sizeof(g_u8BinBuf) / sizeof(HI_U8))
    {
        HI_INFO_PMOC("x5hdtest.bin is bigger than %d Bytes!\n", sizeof(g_u8BinBuf) / sizeof(HI_U8));
        fclose(fb);
        return HI_FAILURE;
    }

    fseek(fb, 0, SEEK_SET);
    if (fread(g_u8BinBuf, 1, len, fb) != len)
    {
        HI_INFO_PMOC("fread err:%s :%d !\n", __FUNCTION__, __LINE__);
        fclose(fb);
        return HI_FAILURE;
    }

    fclose(fb);
    g_u32CodeSize = len;

    return HI_SUCCESS;
}

HI_S32 SetWifiStandbyResume(HI_VOID)
{
    HI_S32 fd;
    HI_S8 fbuf[100];
    pid_t pid;

    fd = open(PID_FILE, O_RDONLY, 0666);
    if(fd < 0) 
    {
        HI_INFO_PMOC("SAMPLE_PS: Cann't open '%s'\n", PID_FILE);
        return HI_FAILURE;
    }

    /* read pid in pid file */
    memset(fbuf, 0, sizeof(fbuf));
    if (read(fd, fbuf, sizeof(fbuf)) < 0) 
    {
        HI_INFO_PMOC("SAMPLE_PS: Cann't read '%s'\n", PID_FILE);
        close(fd);
        return HI_FAILURE;
    }
    close(fd);

    pid = atoi(fbuf);

    kill(pid, SIGPWR);

    sleep(2);

    return HI_SUCCESS;
}

int standbyFlag = HI_FALSE;
int poweroff()
{
    if (HI_FALSE == standbyFlag)
    {
        closeAvPlay();
        HIADP_Disp_DeInit();
        standbyFlag = HI_TRUE;
    }
    else
    {
        system("reboot");
    }
}

HI_S32  enter_standby()
{
    HI_U32 i;
    HI_S32 ret;
    HI_U32 u32Period;
    HI_UNF_PMOC_MODE_E mode;
    HI_UNF_PMOC_WKUP_S wakeup = {
        0
    };
    HI_UNF_PMOC_DEV_TYPE_S devType = {
        HI_UNF_IR_CODE_NEC_SIMPLE, 
        HI_UNF_KEYLED_TYPE_74HC164
    };
    HI_UNF_PMOC_ACTUAL_WKUP_E actual;
    HI_UNF_PMOC_STANDBY_MODE_S standbyMode = {
        0
    };


    //poweroff();
    //return;
    HI_UNF_KEY_Close();
    ret = HI_UNF_PMOC_Init();
    if (HI_SUCCESS != ret)
    {
        HI_INFO_PMOC("HI_UNF_PMOC_Init err, 0x%08x !\n", ret);
        return ret;
    }

   
    memset(&devType, 0, sizeof(HI_UNF_PMOC_DEV_TYPE_S));
    
    devType.irtype = HI_UNF_IR_CODE_NEC_SIMPLE;
    
    devType.kltype = HI_UNF_KEYLED_TYPE_GPIOKEY;

    ret = HI_UNF_PMOC_SetDevType(&devType);
    if (HI_SUCCESS != ret)
    {
        HI_INFO_PMOC("HI_UNF_PMOC_SetDevType err, 0x%08x !\n", ret);
        HI_UNF_PMOC_DeInit();
        return ret;
    }

    memset(&wakeup, 0, sizeof(HI_UNF_PMOC_WKUP_S));

    wakeup.u32WakeUpTime = 5;
    
    // 2.1
    wakeup.u32IrPmocNum = 1;
    wakeup.u32IrPowerKey0[0] = 0x0;
    wakeup.u32IrPowerKey1[0] = 0x0;


    // 2.2
    wakeup.u32KeypadPowerKey = 0x0;
    wakeup.bResumeResetEnable = 1;
    wakeup.bGpioWakeUpEnable = 0;
    
    ret = HI_UNF_PMOC_SetWakeUpAttr(&wakeup);
    if (HI_SUCCESS != ret)
    {
        HI_INFO_PMOC("HI_UNF_PMOC_SetWakeUpAttr err, 0x%08x !\n", ret);
        HI_UNF_PMOC_DeInit();
        return ret;
    }

    ret = HI_UNF_PMOC_SetScene(HI_UNF_PMOC_SCENE_STANDARD);
    if (HI_SUCCESS != ret)
    {
        HI_INFO_PMOC("HI_UNF_PMOC_SetScene err, 0x%08x !\n", ret);
        HI_UNF_PMOC_DeInit();
        return ret;
    }
    //return;
    memset(&standbyMode, 0, sizeof(HI_UNF_PMOC_STANDBY_MODE_S));

   
    standbyMode.u32Mode = 0;
    
    ret = HI_UNF_PMOC_SetStandbyDispMode(&standbyMode);
    if (HI_SUCCESS != ret)
    {
        HI_INFO_PMOC("HI_UNF_PMOC_SetStandbyDispMode err, 0x%08x !\n", ret);
        HI_UNF_PMOC_DeInit();
        return ret;
    }
    

    //SetWifiStandbyResume();
    mode = HI_UNF_PMOC_MODE_SLEEP;
    ret  = HI_UNF_PMOC_SwitchSystemMode(mode, &actual);
    if (HI_SUCCESS != ret)
    {
        HI_INFO_PMOC("HI_UNF_PMOC_SwitchSystemMode err, 0x%08x !\n", ret);
        HI_UNF_PMOC_DeInit();
        return ret;
    }
    
    //SetWifiStandbyResume();

    if (actual == HI_UNF_PMOC_WKUP_IR)
    {
        HI_INFO_PMOC("wakeup by ir !!!\n");
    }
    else if (actual == HI_UNF_PMOC_WKUP_KEYLED)
    {
        HI_INFO_PMOC("wakeup by key !!!\n");
    }
    else if (actual == HI_UNF_PMOC_WKUP_TIMEOUT)
    {
        HI_INFO_PMOC("wakeup by timeout !!!\n");
    }
    else if (actual == HI_UNF_PMOC_WKUP_ETH)
    {
        HI_INFO_PMOC("wakeup by ethernet !!!\n");
    }
    else if (actual == HI_UNF_PMOC_WKUP_USB)
    {
        HI_INFO_PMOC("wakeup by usb !!!\n");
    }
    else if (actual == HI_UNF_PMOC_WKUP_GPIO)
    {
        HI_INFO_PMOC("wakeup by gpio !!!\n");
    }
    else
    {
        HI_INFO_PMOC("wakeup by no mode ??? \n");
    }

    HI_UNF_PMOC_GetStandbyPeriod(&u32Period);
    
    HI_INFO_PMOC("\n standby period = %d \n", u32Period);
    
    HI_INFO_PMOC("%%%%%%%% cnt = %d %%%%%%%% \n", i);

    HI_UNF_PMOC_DeInit();

    return HI_SUCCESS;
}

